package test.scan.annotation;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;
import org.springframework.util.ReflectionUtils;

@Component
public class DataAccessAnnotationProcessor implements BeanPostProcessor {

    private static final Logger logger = LoggerFactory.getLogger(DataAccessAnnotationProcessor.class);
    private ConfigurableListableBeanFactory configurableBeanFactory;
 
    @Autowired
    public DataAccessAnnotationProcessor(ConfigurableListableBeanFactory beanFactory) {
        this.configurableBeanFactory = beanFactory;
    }
 
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) 
      throws BeansException {
//        logger.info("before - bean:{},name:{}",bean,beanName);
        this.scanDataAccessAnnotation(bean);
        return bean;
    }
 
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) 
      throws BeansException {
//        logger.info("post - bean:{},name:{}",bean,beanName);
        this.scanDataAccessAnnotation(bean);
        return bean;
    }
 
    protected void scanDataAccessAnnotation(Object bean) {
        Class<?> managedBeanClass = bean.getClass();
        ReflectionUtils.MethodCallback methodCallback =  new DataAccessMethodCallback(configurableBeanFactory, bean);
        ReflectionUtils.doWithMethods(managedBeanClass, methodCallback);
    }
}